package org.vacoor.xqq.ui.comp.tree;

import org.vacoor.xqq.core.bean.Buddy;
import org.vacoor.xqq.core.bean.Category;
import org.vacoor.xqq.core.bean.Peer;
import org.vacoor.xqq.core.bean.Status;

import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeNode;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

/**
 * 分类节点
 *
 * @author: Vacoor
 */
public class CategoryNode extends ShakeableNode {
    private BuddiesStatusMonitor monitor = new BuddiesStatusMonitor();
    private String name;
    private int onlineCount;

    /**
     * @param category
     */
    public CategoryNode(Category<Peer> category) {
        this(category.getIndex(), category.getName());

        for (Peer peer : category) {
            PeerNode node = new PeerNode(peer);
            if (peer instanceof Buddy && !Status.isInvisible(((Buddy) peer).getStatus())) {
                insert(node, 0);
            } else {
                add(node);
            }
        }
    }

    public CategoryNode(long id, String name) {
        super(id);
        setName(name);
    }

    @Override
    public boolean isLeaf() {
        return false;
    }

    @Override
    public void insert(MutableTreeNode newChild, int childIndex) {

        // 为所有可监听属性变化的子元素添加状态监听
        if (newChild instanceof IdentifiableAndObservableDataNode) {
            ((IdentifiableAndObservableDataNode) newChild).addPropertyChangeListener(monitor);
        }
        super.insert(newChild, childIndex);
    }

    @Override
    public void remove(int childIndex) {
        TreeNode node = getChildAt(childIndex);
        if (node instanceof IdentifiableAndObservableDataNode) {
            ((IdentifiableAndObservableDataNode) node).removePropertyChangeListener(monitor);
        }
        super.remove(childIndex);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        String old = this.name;
        this.name = name;
        firePropertyChange("name", old, name);
    }

    public int getOnlineCount() {
        return onlineCount;
    }

    public void setOnlineCount(int onlineCount) {
        int old = this.onlineCount;
        this.onlineCount = Math.max(onlineCount, 0);
        this.onlineCount = Math.min(this.getOnlineCount(), getTotalCount());
        firePropertyChange("onlineCount", old, onlineCount);
    }

    public int getTotalCount() {
        return getChildCount();
    }

    @Override
    public String toString() {
        return name + " [" + getOnlineCount() + "/" + getTotalCount() + ']';
    }

    @Override
    protected int doNextShakeStatus() {
        return currentShakeStatus == NORMAL ? HIDDEN : NORMAL;
    }

    /**
     * 好友状态监视器
     */
    private class BuddiesStatusMonitor implements PropertyChangeListener {

        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            Object oldValue = evt.getOldValue();
            Object newValue = evt.getNewValue();
            if (!(oldValue instanceof Status) || !(newValue instanceof Status)) {
                return;
            }
            Status oldStatus = (Status) oldValue;
            Status newStatus = (Status) newValue;
            // offline --> online
            if (Status.isInvisible(oldStatus) && !Status.isInvisible(newStatus)) {
                setOnlineCount(getOnlineCount() + 1);
                return;
            }

            // online --> offline
            if (!Status.isInvisible(oldStatus) && Status.isInvisible(newStatus)) {
                setOnlineCount(getOnlineCount() - 1);
                return;
            }
        }
    }

}
